// --- this is stolen from MDC

// Test protocol related
const kSCHEME = "widget";
const kPROTOCOL_NAME = "WidgetURI — Protocol handler for widget:// URIs";
const kPROTOCOL_CONTRACTID = "@mozilla.org/network/protocol;1?name=" + kSCHEME;
const kPROTOCOL_CID = Components.ID("cc5875c0-0e37-48ac-a842-83f6b69574de");

// Mozilla defined
const kSIMPLEURI_CONTRACTID = "@mozilla.org/network/simple-uri;1";
const kIOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
const nsISupports = Components.interfaces.nsISupports;
const nsIIOService = Components.interfaces.nsIIOService;
const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
const nsIURI = Components.interfaces.nsIURI;


function WidgetURI () {}
WidgetURI.prototype = {
    QueryInterface: function (iid) {
        if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports)) throw Components.results.NS_ERROR_NO_INTERFACE;
        return this;
    },

    scheme: kSCHEME,
    defaultPort: -1,
    protocolFlags:  nsIProtocolHandler.URI_STD, //                        |
                    // nsIProtocolHandler.URI_NOAUTH                     | // XXX not sure this is true; we might need it
                    // nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT  | // not sure what this entails
                    // nsIProtocolHandler.URI_DANGEROUS_TO_LOAD,//          |
                    // nsIProtocolHandler.URI_IS_LOCAL_FILE              | // might remove this restriction
                    // nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,           // not expected to hit the network (works offline)
  
    allowPort: function (port, scheme) {
        return false;
    },


    newURI:    function (spec, charset, baseURI) {
        var nssu = Components.interfaces.nsIStandardURL;
        var url = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(nssu);
        url.init(nssu.URLTYPE_STANDARD, -1, spec, charset, baseURI);
        return url.QueryInterface(Components.interfaces.nsIURI);
    },

    newChannel: function (uri) {
        var widgeon = Components.classes['@berjon.com/widgeon;1'].getService().wrappedJSObject;
        var u = widgeon.utils;
        if(!uri.schemeIs("widget")) return;
        var widget = widgeon.createWidget(uri.host);
        if (uri.path == "/config.xml") return this.errorChannel("Forbidden: " + uri.spec, uri);
        // XXX maybe other forbiddens
        var path = uri.path.replace(/^\//, "");
        var jarURI = widget.file(path);
        var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
        var channel = ios.newChannel(jarURI, null, null);
        channel.originalURI = uri;
        return channel;
    },
    
    errorChannel:    function (error, uri) {
        var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
        var channel = ios.newChannel('data:text/html;charset=utf-8,<!DOCTYPE html>%0D%0A<html lang%3D"en">%0D%0A <head><title>Error<%2Ftitle><%2Fhead>%0D%0A <body>%0D%0A  <pre style="color: red">ERROR:\n' + error + '<%2Fpre>%0D%0A <%2Fbody>%0D%0A<%2Fhtml>%0D%0A', null, null);
        channel = ios.newChannel(fileURI, null, null);
        return channel;
    },
}

var WidgetURIFactory = new Object();
WidgetURIFactory.createInstance = function (outer, iid) {
    if (outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION;
    if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports)) throw Components.results.NS_ERROR_NO_INTERFACE;
    return new WidgetURI();
}

// XXX the name reflects just how deeply I understand what's going on here
var CopyPastedModule = new Object();
CopyPastedModule.registerSelf = function (compMgr, fileSpec, location, type) {
    compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
    compMgr.registerFactoryLocation(kPROTOCOL_CID,
                                    kPROTOCOL_NAME,
                                    kPROTOCOL_CONTRACTID,
                                    fileSpec, 
                                    location, 
                                    type);
}
CopyPastedModule.getClassObject = function (compMgr, cid, iid) {
    if (!cid.equals(kPROTOCOL_CID)) throw Components.results.NS_ERROR_NO_INTERFACE;
    if (!iid.equals(Components.interfaces.nsIFactory)) throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
    return WidgetURIFactory;
}
CopyPastedModule.canUnload = function (compMgr) {
    return true;
}
function NSGetModule (compMgr, fileSpec) {
    return CopyPastedModule;
}

